package com.zkh.myutils.proxy.util;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import com.zkh.myutils.utils.Utils;

import jdk.internal.org.objectweb.asm.Type;

//参数类型处理器
public class TypeHandler {
	//帧总长度
	private int total = 0;
	//数量
	private int number = 0;
	//方法签名
	private String autograph;
	//所有类型
	private List<TypeBean> beanList;

	//格式化类型
	public static TypeHandler getTypeList(Type[] types){
		//处理器
		TypeHandler handler = new TypeHandler();
		//初始化类型容器
		handler.setBeanList(new ArrayList<>());
		//方法签名
		StringBuilder sb = new StringBuilder("autograph：");
		//遍历赋值
		for(Type t: types) {
			//大小
			int size = t.getSize();
			//保存实体
			handler.getBeanList().add(new TypeBean(t, size, t.getDescriptor(), t.getClassName()));
			//累计长度
			handler.addTotal(size);
			//完善签名
			sb.append(t.getDescriptor());
		}
		//保存签名
		handler.setAutograph(Utils.md5Short(sb.toString()));
		//保存数量
		handler.setNumber(handler.getBeanList().size());
		//返回
		return handler;
	}
	
	/**
	 * 获取visitFrame的第3个参数
	 * @param proxyClassName 类型，数组的第一个参数
	 * @return
	 */
	public Object[] getFrameView(String proxyClassName) {
		//初始化
		Object[] arr = new Object[number + 2];
		//固定参数
		arr[0] = proxyClassName;
		arr[number + 1] = "[Ljava/lang/Object;";
		//变动参数
		for(int i=0,len=number; i<len; i++) {
			//获取bean
			TypeBean b = beanList.get(i);
			//设置类型（{proxyClassName, "java/lang/Integer", Opcodes.INTEGER, "java/lang/String", Opcodes.DOUBLE, "[S", "[Ljava/lang/Object;"}）
			arr[i + 1] = b.isOriginType() ? b.getArrType() : b.getSpecial();
		}
		//返回
		return arr;
	}
	
	/**
	 * 遍历bean
	 */
	public void beanForeach(Consumer<TypeIterator<TypeBean>> biConsumer) {
		//帧累计
		int frame = 0;
		//遍历
		for(int i=0; i<number; i++) {
			//当前bean
			TypeBean b = beanList.get(i);
			//帧累计
			frame += b.getLength();
			//保存
			biConsumer.accept(new TypeIterator<TypeBean>(i, frame, b));
		}
	}
	
	public void addTotal(int size) {
		total += size;
	}
	
	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}

	public List<TypeBean> getBeanList() {
		return beanList;
	}

	public void setBeanList(List<TypeBean> beanList) {
		this.beanList = beanList;
	}

	public String getAutograph() {
		return autograph;
	}

	public void setAutograph(String autograph) {
		this.autograph = autograph;
	}

	@Override
	public String toString() {
		return "TypeHandler [total=" + total + ", number=" + number
				+ ", autograph=" + autograph + ", beanList=" + beanList + "]";
	}
}
